package com.lzy.netty.utils;

import com.lzy.pojo.netty.NettyServerNode;
import com.lzy.utils.JsonUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class ZookeeperRegister {

    public static void registerNettyServer(String nodeName, String ip, int port) throws Exception {
        CuratorFramework client = CuratorConfig.getClient();
        String path = "/" + nodeName;
        Stat stat = client.checkExists().forPath(path);
        // 判断根路径的结点是否存在
        if(stat == null){
            // 不存在，则递归创建
            client.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(path);
        } else{
            System.out.println("节点已存在" + stat);
        }

        // 创建对应的临时节点，值可以放入在线人数，初始化人数为0
        NettyServerNode nettyServerNode = new NettyServerNode();
        nettyServerNode.setIp(ip);
        nettyServerNode.setPort(port);
        String nodeJson = JsonUtils.objectToJson(nettyServerNode);
        client.create()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(path + "/lzy-", nodeJson.getBytes());
    }

    public static String getLocalIp() throws Exception{
        String ip = null;
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface networkInterface = interfaces.nextElement();

            // 检查网络接口是否处于活动状态
            if (!networkInterface.isUp() || networkInterface.isLoopback()) {
                continue;
            }

            // 判断是否为WiFi接口（不同操作系统的命名规则）
            String name = networkInterface.getName().toLowerCase();
            if (name.contains("wlan") || name.contains("wifi") ||
                    name.contains("wireless") || name.startsWith("en0")) { // macOS WiFi接口通常是en0

                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    // 选择IPv4地址且非回环地址
                    if (!address.isLoopbackAddress() && address instanceof Inet4Address) {
                        ip = address.getHostAddress();
                        System.out.println("本机IP地址" + ip);
                        return address.getHostAddress();
                    }
                }
            }
        }
        return null;
    }

    /**
     * 增加netty的在线人数，并保存到zookeeper中
     * @param nettyServerNode
     */
    public static void incrementOnlineCounts(NettyServerNode nettyServerNode) throws Exception {
        dealOnlineCounts(nettyServerNode,1);
    }

    /**
     * 减少netty的在线人数，并保存到zookeeper中
     * @param nettyServerNode
     */
    public static void decrementOnlineCounts(NettyServerNode nettyServerNode) throws Exception {
        dealOnlineCounts(nettyServerNode,-1);
    }

    /**
     * 处理在线人数
     * @param nettyServerNode
     * @param counts
     */
    public static void dealOnlineCounts(NettyServerNode nettyServerNode,Integer counts) throws Exception {
        CuratorFramework curatorClient = CuratorConfig.getClient();
        String path = "/server-list"; // 父节点

        List<String> list = curatorClient.getChildren().forPath(path);
        for (String child : list) {
            // 获取子节点的完整路径
            String childPath = path + "/" + child;
            // 获取子节点的数据
            String nodeData = new String(curatorClient.getData().forPath(childPath));
            NettyServerNode ServerNode = JsonUtils.jsonToPojo(nodeData, NettyServerNode.class);
            if(ServerNode.getIp().equals(nettyServerNode.getIp())
                    && ServerNode.getPort().equals(nettyServerNode.getPort())){
                ServerNode.setOnlineCount(ServerNode.getOnlineCount() + counts);
                // 将处理的值重新写回zookeeper中
                curatorClient.setData().forPath(childPath, JsonUtils.objectToJson(ServerNode).getBytes());
            }
        }

    }
}
